﻿namespace YunQue.WebApi.Middlewares
{
    /// <summary>
    /// 用户上下文中间件
    /// </summary>
    public class UserContextMiddleware
    {
        private readonly RequestDelegate _next;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="next"></param>
        public UserContextMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        /// <summary>
        /// invoke
        /// </summary>
        /// <param name="context"></param>
        /// <param name="userContext"></param>
        /// <param name="serviceProvider"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context, UserContext userContext, IServiceProvider serviceProvider)
        {
            // 从 HttpContext.User 提取用户信息
            var user = context.User;
            if (user.Identity != null && user.Identity.IsAuthenticated)
            {
                userContext.Id = user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
                userContext.Name = user.FindFirst(ClaimTypes.Name)?.Value;
                userContext.TenantCode = user.FindFirst(AppSettingManager.JWT_TENANT)?.Value;
                userContext.SessionId = user.FindFirst(AppSettingManager.JWT_SESSIONID)?.Value;
                var permissionService = serviceProvider.GetRequiredService<PermissionService>();
                userContext.UserPermissions = await permissionService.GetUserPermissionsByUserIdAsync(userContext.Id).ConfigureAwait(false);
                userContext.TenantPermissions = await permissionService.GetTenantPermissionsByCodeAsync(userContext.TenantCode).ConfigureAwait(false);
            }
            context.Request.Headers[AppSettingManager.USERID] = userContext.Id;
            //不是login接口，需要验证token
            if(context.Request.Path.Value.EndsWith("login"))
            {
                //登录接口，token需要从header里面取
                userContext.TenantCode = RASEncryption.Decrypt(context.Request.Headers[AppSettingManager.JWT_TENANT]);
            }
            await _next(context);
        }
    }
}
